﻿using System;

namespace EnterpriseLibraryExtensions.Services.Mapping
{
    /// <summary>
    /// The interface to implement on classes which supports translation from one type to another and needs 
    /// to be registered on the <see cref="EnterpriseLibraryExtensions.Services.Mapping.IEntityTranslatorService"/>.
    /// </summary>
    public interface IEntityTranslator
    {
        /// <summary>
        /// Returns if the implementation supports translating the two types.
        /// </summary>
        /// <param name="targetType">Type to translate to.</param>
        /// <param name="sourceType">Type to translate from.</param>
        /// <returns>If the instance support translating the two types.</returns>
        bool CanTranslate(Type targetType, Type sourceType);

        /// <summary>
        /// Returns if the implementation supports translating the two types.
        /// </summary>
        /// <typeparam name="TTarget">Type to translate to.</typeparam>
        /// <typeparam name="TSource">Type to translate from.</typeparam>
        /// <returns>If the instance support translating the two types.</returns>
        bool CanTranslate<TTarget, TSource>();

        /// <summary>
        /// Translates the source entity into an instance of the target type if the implementations supports it.
        /// </summary>
        /// <param name="service">The implementaiton if <see cref="IEntityTranslatorService"/> which the translator is registered to.</param>
        /// <param name="targetType">The desired type of the target instance.</param>
        /// <param name="source">The instance to translate from.</param>
        /// <returns>The new instance.</returns>
        /// <exception cref="System.InvalidOperationException">Thrown when translator does not support the desired mapping.</exception>
        object Translate(IEntityTranslatorService service, Type targetType, object source);

        /// <summary>
        /// Translates the source entity into an instance of the target type if the implementations supports it.
        /// </summary>
        /// <typeparam name="TTarget">The desired type of the target instance.</typeparam>
        /// <param name="service">The implementaiton if <see cref="IEntityTranslatorService"/> which the translator is registered to.</param>
        /// <param name="source">The instance to translate from.</param>
        /// <returns>The new instance.</returns>
        /// <exception cref="System.InvalidOperationException">Thrown when translator does not support the desired mapping.</exception>
        TTarget Translate<TTarget>(IEntityTranslatorService service, object source);
    }

}
